package com.jerei.plugin.dao.impl;

import com.jerei.plugin.dao.IWcmCommonMenuDetailDao;
import com.jerei.plugin.entity.WcmCommonAdminuser;
import com.jerei.plugin.entity.WcmCommonMenuDetail;
import com.jerei.plugin.utils.JrJdbcTemplate;
import com.jerei.utils.condition.ConditionEntity;
import com.jerei.utils.condition.ConditionTools;
import com.jerei.utils.condition.SQLEntity;
import com.jerei.utils.spring.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.*;
import java.util.*;

/**
 * Created by sunfeihu on 2016/10/20.
 */
@Repository
public class WcmCommonMenuDetailDaoImpl implements IWcmCommonMenuDetailDao {

    @Autowired
    private JrJdbcTemplate jrJdbcTemplate;


    @Override
    public WcmCommonMenuDetail save(WcmCommonMenuDetail entity) {
        final String sql = " insert into wcm_common_menu_detail (uuid,add_date,add_ip,add_user,update_date,update_ip,update_user,gid,sid,menu_no,name,pid,path,plugin_id,icon_small,icon_big,is_show,remark,orderno,link_other,target,window_width,window_height,params,config_link,is_free) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        KeyHolder keyHolder = new GeneratedKeyHolder();
        final WcmCommonMenuDetail finalEntity = entity;
        this.jrJdbcTemplate.getJdbcTemplate().update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
                ps.setObject(1, finalEntity.getUuid());
                ps.setObject(2, new Timestamp(finalEntity.getAddDate().getTime()));
                ps.setObject(3, finalEntity.getAddIp());
                ps.setObject(4, finalEntity.getAddUser());
                ps.setObject(5, new Timestamp(finalEntity.getUpdateDate().getTime()));
                ps.setObject(6, finalEntity.getUpdateIp());
                ps.setObject(7, finalEntity.getUpdateUser());
                ps.setObject(8, finalEntity.getGid());
                ps.setObject(9, finalEntity.getSid());
                ps.setObject(10, finalEntity.getMenuNo());
                ps.setObject(11, finalEntity.getName());
                ps.setObject(12, finalEntity.getPid());
                ps.setObject(13, finalEntity.getPath());
                ps.setObject(14, finalEntity.getPluginId());
                ps.setObject(15, finalEntity.getIconSmall());
                ps.setObject(16, finalEntity.getIconBig());
                ps.setObject(17, finalEntity.getIsShow());
                ps.setObject(18, finalEntity.getRemark());
                ps.setObject(19, finalEntity.getOrderno());
                ps.setObject(20, finalEntity.getLinkOther());
                ps.setObject(21, finalEntity.getTarget());
                ps.setObject(22, finalEntity.getWindowWidth());
                ps.setObject(23, finalEntity.getWindowHeight());
                ps.setObject(24, finalEntity.getParams());
                ps.setObject(25, finalEntity.getConfigLink());
                ps.setObject(26, finalEntity.getIsFree());
                return ps;
            }
        }, keyHolder);
        Long id = keyHolder.getKey().longValue();
        return this.find(id);
    }

    @Override
    public int delete(Long id) {
        final String sql = " delete from wcm_common_menu_detail where id = ? ";
        return this.jrJdbcTemplate.getJdbcTemplate().update(sql, new Object[]{
                id
        });
    }

    @Override
    public int update(WcmCommonMenuDetail entity) {
        final String sql = " update wcm_common_menu_detail set uuid=?,add_date=?,add_ip=?,add_user=?,update_date=?,update_ip=?,update_user=?,gid=?,sid=?,menu_no=?,name=?,pid=?,path=?,plugin_id=?,icon_small=?,icon_big=?,is_show=?,remark=?,orderno=?,link_other=?,target=?,window_width=?,window_height=?,params=?,config_link=?,is_free=? where id = ?";
        return this.jrJdbcTemplate.getJdbcTemplate().update(sql, new Object[]{
                entity.getUuid(), entity.getAddDate(), entity.getAddIp(), entity.getAddUser(), entity.getUpdateDate(), entity.getUpdateIp(), entity.getUpdateUser(), entity.getGid(), entity.getSid(), entity.getMenuNo(), entity.getName(), entity.getPid(), entity.getPath(), entity.getPluginId(), entity.getIconSmall(), entity.getIconBig(), entity.getIsShow(), entity.getRemark(), entity.getOrderno(), entity.getLinkOther(), entity.getTarget(), entity.getWindowWidth(), entity.getWindowHeight(), entity.getParams(), entity.getConfigLink(), entity.getIsFree(),
                entity.getId()
        });
    }

    @Override
    public WcmCommonMenuDetail find(Long id) {
        final String sql = " select * from wcm_common_menu_detail where id = ? ";
        return this.jrJdbcTemplate.getJdbcTemplate().queryForObject(sql, new Object[]{id}, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> find(List<Long> ids) {
        String whereStr = "";
        Object[] params = null;
        if (null != ids && ids.size() > 0) {
            params = new Object[ids.size() + 1];
            params[0] = 0;
            for (int i = 0; i < ids.size(); i++) {
                whereStr += " or id = ? ";
                params[i + 1] = ids.get(i);
            }
        }
        final String sql = " select * from wcm_common_menu_detail where 1 = 1 and ( id = ? " + whereStr + ") ";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, params, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public void save(List<WcmCommonMenuDetail> list) {
        if (null != list && list.size() > 0) {
            final String sql = " insert into wcm_common_menu_detail (uuid,add_date,add_ip,add_user,update_date,update_ip,update_user,gid,sid,menu_no,name,pid,path,plugin_id,icon_small,icon_big,is_show,remark,orderno,link_other,target,window_width,window_height,params,config_link,is_free) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            WcmCommonMenuDetail entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[26];
                objArr[0] = entity.getUuid();
                objArr[1] = entity.getAddDate();
                objArr[2] = entity.getAddIp();
                objArr[3] = entity.getAddUser();
                objArr[4] = entity.getUpdateDate();
                objArr[5] = entity.getUpdateIp();
                objArr[6] = entity.getUpdateUser();
                objArr[7] = entity.getGid();
                objArr[8] = entity.getSid();
                objArr[9] = entity.getMenuNo();
                objArr[10] = entity.getName();
                objArr[11] = entity.getPid();
                objArr[12] = entity.getPath();
                objArr[13] = entity.getPluginId();
                objArr[14] = entity.getIconSmall();
                objArr[15] = entity.getIconBig();
                objArr[16] = entity.getIsShow();
                objArr[17] = entity.getRemark();
                objArr[18] = entity.getOrderno();
                objArr[19] = entity.getLinkOther();
                objArr[20] = entity.getTarget();
                objArr[21] = entity.getWindowWidth();
                objArr[22] = entity.getWindowHeight();
                objArr[23] = entity.getParams();
                objArr[24] = entity.getConfigLink();
                objArr[25] = entity.getIsFree();
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void delete(List<Long> ids) {
        if (null != ids && ids.size() > 0) {
            final String sql = " delete from wcm_common_menu_detail where id = ? ";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            for (int i = 0; i < ids.size(); i++) {
                objArr = new Object[1];
                objArr[0] = ids.get(i);
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void update(List<WcmCommonMenuDetail> list) {
        if (null != list && list.size() > 0) {
            final String sql = " update wcm_common_menu_detail set uuid=?,add_date=?,add_ip=?,add_user=?,update_date=?,update_ip=?,update_user=?,gid=?,sid=?,menu_no=?,name=?,pid=?,path=?,plugin_id=?,icon_small=?,icon_big=?,is_show=?,remark=?,orderno=?,link_other=?,target=?,window_width=?,window_height=?,params=?,config_link=?,is_free=? where id = ?";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            WcmCommonMenuDetail entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[27];
                objArr[0] = entity.getUuid();
                objArr[1] = entity.getAddDate();
                objArr[2] = entity.getAddIp();
                objArr[3] = entity.getAddUser();
                objArr[4] = entity.getUpdateDate();
                objArr[5] = entity.getUpdateIp();
                objArr[6] = entity.getUpdateUser();
                objArr[7] = entity.getGid();
                objArr[8] = entity.getSid();
                objArr[9] = entity.getMenuNo();
                objArr[10] = entity.getName();
                objArr[11] = entity.getPid();
                objArr[12] = entity.getPath();
                objArr[13] = entity.getPluginId();
                objArr[14] = entity.getIconSmall();
                objArr[15] = entity.getIconBig();
                objArr[16] = entity.getIsShow();
                objArr[17] = entity.getRemark();
                objArr[18] = entity.getOrderno();
                objArr[19] = entity.getLinkOther();
                objArr[20] = entity.getTarget();
                objArr[21] = entity.getWindowWidth();
                objArr[22] = entity.getWindowHeight();
                objArr[23] = entity.getParams();
                objArr[24] = entity.getConfigLink();
                objArr[25] = entity.getIsFree();
                objArr[26] = entity.getId();
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public PageBean<WcmCommonMenuDetail> pageDevRoot(int nowPage, int pageSize) {
        final String sql = " select * from wcm_common_menu_detail where menu_no = 1 and ( pid IS NULL or pid = 0 ) order by id desc ";
        return new PageBean<WcmCommonMenuDetail>(sql, null, nowPage, pageSize, new WcmCommonMenuDetailRowerMapper(), this.jrJdbcTemplate.getJdbcTemplate());
    }

    @Override
    public PageBean<WcmCommonMenuDetail> pageGroupRoot(int nowPage, int pageSize, Long gid) {
        final String sql = " select * from wcm_common_menu_detail where menu_no = 2 and gid = ? and ( pid IS NULL or pid = 0 ) order by id desc ";
        return new PageBean<WcmCommonMenuDetail>(sql, new Object[]{gid}, nowPage, pageSize, new WcmCommonMenuDetailRowerMapper(), this.jrJdbcTemplate.getJdbcTemplate());
    }

    @Override
    public PageBean<WcmCommonMenuDetail> page(int nowPage, int pageSize, ConditionEntity conditionEntity) {
        SQLEntity sqlEntity = ConditionTools.conditionEntities2SQL(conditionEntity);
        final String sql = " select * from wcm_common_menu_detail where 1 = 1 " + sqlEntity.getSql() + " order by " + sqlEntity.getOrder();
        return new PageBean<WcmCommonMenuDetail>(sql, sqlEntity.getParams(), nowPage, pageSize, new WcmCommonMenuDetailRowerMapper(), this.jrJdbcTemplate.getJdbcTemplate());
    }

    @Override
    public List<WcmCommonMenuDetail> getRootMenuDetail(WcmCommonAdminuser adminuser) {
        final String sql = "SELECT b.id,b.name,b.is_show,b.plugin_id FROM wcm_common_role_menu_detail a,wcm_common_menu_detail b WHERE a.menu_detail_id = b.id AND b.menu_no = ? AND ( pid IS NULL or pid = 0 ) AND b.is_show = 1 AND a.role_id IN (SELECT role_id FROM wcm_common_role_user WHERE user_id = ?) GROUP BY b.id,b.name,b.is_show,b.plugin_id ORDER BY b.orderno ASC,b.id DESC";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new Object[]{adminuser.getMenuNo(), adminuser.getId()}, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> getDevRootMenuDetailNoPower() {
        final String sql = "SELECT id,name,is_show,plugin_id FROM wcm_common_menu_detail WHERE menu_no = 1 AND ( pid IS NULL or pid = 0 ) ORDER BY orderno ASC,id DESC";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> getGroupRootMenuDetailNoPower(Long gid) {
        final String sql = "SELECT id,name,is_show,plugin_id FROM wcm_common_menu_detail WHERE menu_no = 2 AND ( pid IS NULL or pid = 0 ) ORDER BY orderno ASC,id DESC";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> getMenuDetailsByParentNoPower(Long pid) {
        final String sql = " SELECT id,name,link_other,plugin_id FROM wcm_common_menu_detail WHERE pid = ? ORDER BY orderno ASC,id DESC ";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new Object[]{pid}, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> getMenuDetailsByParent(Long adminuserId, Long pid) {
        final String sql = "SELECT id,name,link_other,plugin_id FROM wcm_common_menu_detail WHERE pid = ? AND id IN ( SELECT wcm_common_role_menu_detail.menu_detail_id FROM wcm_common_role_menu_detail WHERE wcm_common_role_menu_detail.disabled = 0 AND wcm_common_role_menu_detail.role_id IN ( SELECT wcm_common_role_user.role_id FROM wcm_common_role_user WHERE wcm_common_role_user.user_id = ?)) order by orderno asc , id desc ";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new Object[]{pid, adminuserId}, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public List<WcmCommonMenuDetail> getMenuDetailsByRole(Long roleId) {
        final String sql = " SELECT a.id,a.name,a.link_other,a.plugin_id FROM wcm_common_menu_detail a , wcm_common_role_menu_detail b WHERE a.id = b.menu_detail_id AND b.role_id = ? AND b.disabled = 0 order by a.orderno asc , a.id desc ";
        return this.jrJdbcTemplate.getJdbcTemplate().query(sql, new Object[]{roleId}, new WcmCommonMenuDetailRowerMapper());
    }

    @Override
    public void addPowerForRole(Long roleId, Long[] ids) {
        final String sql = " insert into wcm_common_role_menu_detail (role_id,menu_detail_id,disabled,permissions) values (?,?,?,?) ";
        if (null != ids && ids.length > 0) {
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] param = null;
            for (int i = 0; i < ids.length; i++) {
                param = new Object[4];
                param[0] = roleId;
                param[1] = ids[i];
                param[2] = 0;
                param[3] = "view:*,save:*,update:*,print:*,remove:*,export:*,sort:*";
                params.add(param);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }

    }

    @Override
    public void updatePowerForRole(Long roleId, Long[] ids) {
        final String sql = " update wcm_common_role_menu_detail set disabled = 0 where role_id = ? and menu_detail_id = ? ";
        if (null != ids && ids.length > 0) {
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] param = null;
            for (int i = 0; i < ids.length; i++) {
                param = new Object[2];
                param[0] = roleId;
                param[1] = ids[i];
                params.add(param);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void deletePowerForRole(Long roleId, Long[] ids) {
        final String sql = " update wcm_common_role_menu_detail set disabled = 1 where role_id = ? and menu_detail_id = ? ";
        if (null != ids && ids.length > 0) {
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] param = null;
            for (int i = 0; i < ids.length; i++) {
                param = new Object[2];
                param[0] = roleId;
                param[1] = ids[i];
                params.add(param);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void clearPowerForRole(Long roleId) {
        final String sql = " delete from wcm_common_role_menu_detail where role_id = ? ";
        this.jrJdbcTemplate.getJdbcTemplate().update(sql, new Object[]{roleId});
    }

    @Override
    public List<Map<String, Object>> findPermissions(Long[] roleIds) {
        String whereStr = "";
        Object[] params = null;
        if (null != roleIds) {
            params = new Object[roleIds.length + 1];
            params[0] = 0;
            for (int i = 0; i < roleIds.length; i++) {
                params[i + 1] = roleIds[i];
                whereStr += " OR a.role_id = ? ";
            }
        }
        final String sql = "SELECT b.id, b.plugin_id, a.permissions FROM wcm_common_role_menu_detail a, wcm_common_menu_detail b WHERE a.menu_detail_id = b.id AND b.plugin_id IS NOT NULL AND b.plugin_id != '' AND a.disabled = 0 AND ( a.role_id = ? " + whereStr + " )";
        return this.jrJdbcTemplate.getJdbcTemplate().queryForList(sql, params);
    }
}

class WcmCommonMenuDetailRowerMapper implements RowMapper<WcmCommonMenuDetail> {
    @Override
    public WcmCommonMenuDetail mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Set<String> fieldSet = new HashSet<String>();
        for (int i = 1; i <= columnCount; i++) {
            fieldSet.add(rsmd.getColumnName(i));
        }
        WcmCommonMenuDetail entity = new WcmCommonMenuDetail();
        if (fieldSet.contains("id")) {
            entity.setId(rs.getLong("id"));
        }
        if (fieldSet.contains("uuid")) {
            entity.setUuid(rs.getString("uuid"));
        }
        if (fieldSet.contains("add_date")) {
            if (null != rs.getTimestamp("add_date")) {
                entity.setAddDate(new java.util.Date(rs.getTimestamp("add_date").getTime()));
            } else {
                entity.setAddDate(null);
            }
        }
        if (fieldSet.contains("add_ip")) {
            entity.setAddIp(rs.getString("add_ip"));
        }
        if (fieldSet.contains("add_user")) {
            entity.setAddUser(rs.getString("add_user"));
        }
        if (fieldSet.contains("update_date")) {
            if (null != rs.getTimestamp("update_date")) {
                entity.setUpdateDate(new java.util.Date(rs.getTimestamp("update_date").getTime()));
            } else {
                entity.setUpdateDate(null);
            }
        }
        if (fieldSet.contains("update_ip")) {
            entity.setUpdateIp(rs.getString("update_ip"));
        }
        if (fieldSet.contains("update_user")) {
            entity.setUpdateUser(rs.getString("update_user"));
        }
        if (fieldSet.contains("gid")) {
            entity.setGid(rs.getLong("gid"));
        }
        if (fieldSet.contains("sid")) {
            entity.setSid(rs.getLong("sid"));
        }
        if (fieldSet.contains("menu_no")) {
            entity.setMenuNo(rs.getInt("menu_no"));
        }
        if (fieldSet.contains("name")) {
            entity.setName(rs.getString("name"));
        }
        if (fieldSet.contains("pid")) {
            entity.setPid(rs.getLong("pid"));
        }
        if (fieldSet.contains("path")) {
            entity.setPath(rs.getString("path"));
        }
        if (fieldSet.contains("plugin_id")) {
            entity.setPluginId(rs.getString("plugin_id"));
        }
        if (fieldSet.contains("icon_small")) {
            entity.setIconSmall(rs.getString("icon_small"));
        }
        if (fieldSet.contains("icon_big")) {
            entity.setIconBig(rs.getString("icon_big"));
        }
        if (fieldSet.contains("is_show")) {
            entity.setIsShow(rs.getInt("is_show"));
        }
        if (fieldSet.contains("remark")) {
            entity.setRemark(rs.getString("remark"));
        }
        if (fieldSet.contains("orderno")) {
            entity.setOrderno(rs.getInt("orderno"));
        }
        if (fieldSet.contains("link_other")) {
            entity.setLinkOther(rs.getString("link_other"));
        }
        if (fieldSet.contains("target")) {
            entity.setTarget(rs.getString("target"));
        }
        if (fieldSet.contains("window_width")) {
            entity.setWindowWidth(rs.getInt("window_width"));
        }
        if (fieldSet.contains("window_height")) {
            entity.setWindowHeight(rs.getInt("window_height"));
        }
        if (fieldSet.contains("params")) {
            entity.setParams(rs.getString("params"));
        }
        if (fieldSet.contains("config_link")) {
            entity.setConfigLink(rs.getString("config_link"));
        }
        if (fieldSet.contains("is_free")) {
            entity.setIsFree(rs.getInt("is_free"));
        }
        return entity;
    }
}